/* Using JRE 1.7.0_07
 * 
 * File: ReportView.java
 * @author Wen-Fan Hsieh
 * Email: blueseadream826@gmail.com
 * 
 * Date Created: Oct 15, 2012
 * Date Modified: Oct 30, 2012 
 */

package edu.bu.cs673.superkids123.parents.view;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.border.TitledBorder;
import javax.swing.table.AbstractTableModel;

import edu.bu.cs673.superkids123.AbstractFrame;
import edu.bu.cs673.superkids123.AbstractNavigationView;
import edu.bu.cs673.superkids123.children.model.CompletedGame;
import edu.bu.cs673.superkids123.children.model.CompletedLesson;
import edu.bu.cs673.superkids123.common.model.Child;
import edu.bu.cs673.superkids123.common.model.User;
import edu.bu.cs673.superkids123.parents.controller.ReportController;

public class ReportView extends AbstractNavigationView implements KeyListener, ActionListener {

	JTabbedPane tabbedPane;
	private JComboBox chooseChild;
	private JTable lessonTable;
	private JTable gameTable;
	
//	private int ROW_COUNT = 3;
	private int GRID_GAP = 5;
	
	public ReportView(AbstractFrame mainFrame) {
		super(mainFrame);
	}

	/**
	 * @wbp.parser.entryPoint
	 */
	protected JPanel layout() {
		
		JPanel p = new JPanel();
		p.setLayout(new BorderLayout(15, 10));
		
		//overall statistics
		JPanel info = new JPanel();
		info.setLayout(new GridLayout(4, 2, GRID_GAP, GRID_GAP));
		info.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
		TitledBorder b = BorderFactory.createTitledBorder("Overall Statistics");
		info.setBorder(b);
		p.add(info, BorderLayout.NORTH);
		
		JLabel overall = new JLabel("Overall Usage: ");
		//overall.setLocation();
		info.add(overall);
		
		long totalTime = getMainFrame().getController(ReportController.class).getTotalTime().getTime();
		long sec = (totalTime / 1000) % 60;
		long min = ((totalTime / 1000) / 60) % 60;
		long hr = ((totalTime / 1000) / 60) / 60;
		JLabel overUsage = new JLabel(hr + " hours, " + min + " mins, " + sec + " seconds");   
		//overall.setLocation();
		info.add(overUsage);
		
		JLabel total1 = new JLabel("Total Lesson Play Times: ");
		info.add(total1);
		
		int totalPlayLesson = getMainFrame().getController(ReportController.class).getTotalLesson();
		JLabel totalLesson = new JLabel(String.valueOf(totalPlayLesson) + " times");   
		info.add(totalLesson);
		
		JLabel avg = new JLabel("Total Game Play Times: ");
		info.add(avg);
		
		int totalPlayGame = getMainFrame().getController(ReportController.class).getTotalGame();
		JLabel totalGame = new JLabel(String.valueOf(totalPlayGame) + " times");    
		info.add(totalGame);
		
		JLabel most = new JLabel("Most Play Child: ");
		info.add(most);
		
		String mostChild = getMainFrame().getController(ReportController.class).getMostChild();
		JLabel mostPlayChild = new JLabel(mostChild);
		info.add(mostPlayChild);
		
		
		
		//progress statistics
		JPanel progressInfo = new JPanel();
		
		GridBagLayout gblProgressInfo = new GridBagLayout();
		gblProgressInfo.columnWidths = new int[] { 0, 0 };
		gblProgressInfo.rowHeights = new int[] { 0, 0, 0 };		
		progressInfo.setLayout(gblProgressInfo);
		
		progressInfo.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
		TitledBorder pb = BorderFactory.createTitledBorder("Children Progress");
		progressInfo.setBorder(pb);
		p.add(progressInfo, BorderLayout.CENTER);
		
		//choose child name
		List<Child> children = getMainFrame().getController(ReportController.class).getAllChildren();
		
		JLabel childLabel = new JLabel("Select Child: ", SwingConstants.RIGHT);
		GridBagConstraints gbcChildLabel = new GridBagConstraints();
		gbcChildLabel.gridx = gbcChildLabel.gridy = 0;
		gbcChildLabel.anchor = GridBagConstraints.EAST;
		gbcChildLabel.fill = GridBagConstraints.BOTH;
		progressInfo.add(childLabel, gbcChildLabel);
		
		chooseChild = new JComboBox();
		
		for (int index = 0; index < children.size(); index++)
		{
			Child child = children.get(index);
			chooseChild.addItem(child.getName());
		}
		
		chooseChild.setSize(10, 10);
		chooseChild.addActionListener(this);
		GridBagConstraints gbcComboBox = new GridBagConstraints();
		gbcComboBox.gridx = 1;
		gbcComboBox.gridy = 0;
		progressInfo.add(chooseChild, gbcComboBox);
		
		tabbedPane = new JTabbedPane();
		
		//show lesson progress		
		JPanel lessonContent = new JPanel();
		lessonContent.setLayout(new BorderLayout(15, 10));

		lessonTable = new JTable(new LessonTableModel());
		lessonTable.setPreferredScrollableViewportSize(new Dimension(500, 150));
		lessonTable.setFillsViewportHeight(true);
		
		JScrollPane lessonScrollPane = new JScrollPane(lessonTable);
		lessonContent.add(lessonScrollPane, BorderLayout.CENTER);
		
		tabbedPane.addTab("Lesson Progress", lessonContent);
		
		//show game grade
		JPanel gameContent = new JPanel();
		gameContent.setLayout(new BorderLayout(15, 10));
		
		gameTable = new JTable(new GameTableModel());
		gameTable.setPreferredScrollableViewportSize(new Dimension(500, 150));
		gameTable.setFillsViewportHeight(true);
		
		JScrollPane gameScrollPane = new JScrollPane(gameTable);
		gameContent.add(gameScrollPane);
		
		tabbedPane.addTab("Game Report", gameContent);
		
		GridBagConstraints gbcTabPane = new GridBagConstraints();
		gbcTabPane.gridx = 0;
		gbcTabPane.gridy = 1;
		gbcTabPane.weightx = gbcTabPane.weighty = 1.0;
		gbcTabPane.gridwidth = 2;
		progressInfo.add(tabbedPane, gbcTabPane);
		
		// Chrome adjustments
		this.setAvatarVisible(false);
		this.setParentsButtonVisible(false);
		
		return p;
		
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		
		if (e.getSource() instanceof JComboBox) {
			String name = chooseChild.getSelectedItem().toString();
			getMainFrame().getController(ReportController.class).setSelectedChild(name);
			((LessonTableModel) lessonTable.getModel()).setLesson();
			((LessonTableModel) lessonTable.getModel()).fireTableDataChanged();
			((GameTableModel) gameTable.getModel()).setGame();
			((GameTableModel) gameTable.getModel()).fireTableDataChanged();
		}
	}

	@Override
	public void keyPressed(KeyEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void keyReleased(KeyEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void keyTyped(KeyEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public String getTitle() {
		// TODO Auto-generated method stub
		return "Reports";
	}

	@Override
	public String getBorderTitle() {
		// TODO Auto-generated method stub
		return "General Statistics";
	}
	
	public class LessonTableModel extends AbstractTableModel {
		private static final long serialVersionUID = 1L;
		private String[] columns = {"Lesson Name", "Start Date", "Play Time", "Status"};
		private List<CompletedLesson> lesson = getMainFrame().getController(ReportController.class).getCompletedLessons();
		
		public String getColumnName(int col) {
			return columns[col];
		}
		
		/**
		 * Clears the table and repopulates it with lesson data from selected
		 * child
		 */
		public void setLesson() {
			lesson.clear();
			lesson = getMainFrame().getController(ReportController.class).getCompletedLessons();
		}
		
		@Override
		public int getColumnCount() {
			// TODO Auto-generated method stub
			return columns.length;
		}

		@Override
		public int getRowCount() {
			// TODO Auto-generated method stub
			return lesson.size();
		}

		@Override
		public Object getValueAt(int rowIndex, int colIndex) {
			// TODO Auto-generated method stub
			CompletedLesson compLesson = lesson.get(rowIndex);
			
			switch (colIndex) {
			case 0:
				return compLesson.getLesson().getName();
			case 1:
				return compLesson.getStartDate();
			case 2:
				long time = compLesson.getEndDate().getTime() - compLesson.getStartDate().getTime();
				long seconds = (time / 1000);
				return String.format("%s seconds", seconds);
			case 3:
				if(compLesson.isCompleted())
					return "Completed";
				else
					return "Incomplete";
			}
			return "";
		}
		
	}
	
	public class GameTableModel extends AbstractTableModel {
		private static final long serialVersionUID = 1L;
		private String[] columns = {"Game Name", "Start Date", "Play Time", "Score"};
		// TODO Disabled getting from database until Game side people implement their stat saving functions
		//private List<CompletedGame> game = new ArrayList<CompletedGame>();
		private List<CompletedGame> game = getMainFrame().getController(ReportController.class).getCompletedGame();
		
		public String getColumnName(int col) {
			return columns[col];
		}
		
		public void setGame() {
			game.clear();
			game = getMainFrame().getController(ReportController.class).getCompletedGame();
		}
		
		@Override
		public int getColumnCount() {
			// TODO Auto-generated method stub
			return columns.length;
		}
		@Override
		public int getRowCount() {
			// TODO Auto-generated method stub
			return game.size();
		}
		@Override
		public Object getValueAt(int rowIndex, int colIndex) {
			// TODO Auto-generated method stub
			CompletedGame compGame = game.get(rowIndex);
			
			switch (colIndex) {
			case 0:
				return compGame.getGame().getName();
			case 1:
				return compGame.getStartDate();
			case 2:
				long time = compGame.getEndDate().getTime() - compGame.getStartDate().getTime();
				long seconds = (time / 1000);
				return String.format("%s seconds", seconds);
			case 3:
				return compGame.getScore();
			}
			return "";
		}
		
	}

}
